package org.swimv2.sessions;

import java.util.Collection;
import java.util.Set;

import javax.ejb.Stateless;
import javax.naming.Context;
import javax.persistence.EntityExistsException;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.PersistenceException;
import javax.persistence.Query;

import org.jboss.ejb3.annotation.RemoteBinding;
import org.swimv2.entities.Skill;
import org.swimv2.entities.User;
import org.swimv2.interfaces.SearchManagerRemote;
import org.swimv2.interfaces.SkillManagerRemote;
import org.swimv2.utils.ContextUtil;

/**
 * Session Bean implementation class SkillManager
 */
@Stateless
@RemoteBinding(jndiBinding="SkillManagerJNDI")
public class SkillManager implements SkillManagerRemote {

	@PersistenceContext(unitName="JPADB")
    private EntityManager manager;

	
	@Override
	public Skill getSkill(int id) {
		Skill s;
		
		try {
			Query q = manager.createNamedQuery("Skill.getSkillById");
			q.setParameter("id", id);
			s = (Skill) q.getSingleResult();
		}
		catch (Exception e) {
			e.printStackTrace();
			return null;
		}
		return s;
	}
	
	
	@Override
	public Collection<Skill> listAllActiveSkills() {
		
		String q = "SELECT s FROM Skill AS s WHERE s.active = :status ORDER BY s.name ASC"; 
		
		Query que = manager.createQuery(q);
		
		que.setParameter("status", true);
		
		Collection<Skill> res = (Collection<Skill>) que.getResultList();
		
		return res;
	}

	@Override
	public Collection<Skill> listAllSkillReq() {
		
		String q = "SELECT s FROM Skill AS s WHERE s.active = false ORDER BY s.name ASC"; 
		
		Query que = manager.createQuery(q);
		
		Collection<Skill> res = (Collection<Skill>) que.getResultList();
		
		return res;
	}

	@Override
	public Collection<Skill> listUserSkills(User us) {
		
		String q = "SELECT s FROM User AS u, IN(u.skills) s WHERE u = :user ORDER BY s.name ASC"; 
		
		Query que = manager.createQuery(q);
		
		que.setParameter("user", us);
		
		Collection<Skill> res = (Collection<Skill>) que.getResultList();
		
		return res;
	}

	
	@Override
	public Skill addSkill(String name) {
		try {
			Skill s = new Skill();
			s.setName(name);
			s.setActive(true);
			manager.persist(s);
			return s;
		}
		catch (EntityExistsException e) {
			e.printStackTrace();
			return null;
		}
	}
	
	@Override
	public Skill addSkill(Skill skill) {
		try {
			skill.setActive(true);
			manager.persist(skill);
			return skill;
		}
		catch (EntityExistsException e) {
			e.printStackTrace();
			return null;
		}
	}
	
	
	@Override
	public Skill addSkillReq(Skill skill) {
		try {
			skill.setActive(false);
			manager.persist(skill);
			return skill;
		}
		catch (Exception e) {
			e.printStackTrace();
			return null;
		}
	}

	@Override
	public Skill activateSkill(Skill skill) {
		
		if (skill.getActive() == false) {
			
			String q = "UPDATE Skill s SET s.active = true WHERE s = :skill";
			
			manager.flush();
		
			Query que = manager.createQuery(q);
			que.setParameter("skill", skill);
			que.executeUpdate();
			
			return skill;
		}
		
		return null;
		
	}

	@Override
	public boolean removeSkill(Skill skill) {
		try {
			String q = "DELETE FROM Skill s WHERE s = :skill";
			manager.flush();
			Query que = manager.createQuery(q);
			que.setParameter("skill", skill);
			
			return que.executeUpdate() > 0;
		}
		catch (PersistenceException e) {
			e.printStackTrace();
			return false;
		}
	}


	@Override
	public boolean addSkillUser(User user, Skill skill) {
		try {
//			user.getSkills().add(skill);
			/*
			Context ctx = ContextUtil.getInitialContext();
			SearchManagerRemote mgr_s = (SearchManagerRemote) ctx.lookup("SearchManagerJNDI");
			User u = mgr_s.getUserById(user.getId());
			
			Set<Skill> sList = u.getSkills();
			sList.add(skill);
			u.setSkills(sList);*/
			
//			String q = "UPDATE User u SET u.skills = :skill WHERE u = :user";
			

			user = manager.merge(user);
			
			if (skill.getId() > 0) {
				skill = manager.merge(skill);
				user.getSkills().add(skill);
			}
			else {
				Skill s = addSkill(skill);
				user.getSkills().add(s);
			}
			
			manager.flush();
					
//			Query que = manager.createQuery(q);
//			
//			que.setParameter("skill", u.getSkills());
//			que.setParameter("user", u);
//			
//			return que.executeUpdate() > 0;
			return true;
		}
		catch (Exception e) {
			e.printStackTrace();
			return false;
		}
		
	}


	@Override
	public boolean removeSkillUser(User user, Skill skill) {
		try {
//			user.getSkills().remove(skill);
//			Context ctx = ContextUtil.getInitialContext();
//			SearchManagerRemote mgr_s = (SearchManagerRemote) ctx.lookup("SearchManagerJNDI");
//			User u = mgr_s.getUserById(user.getId());
//			
//			Set<Skill> sList = u.getSkills();
//			sList.remove(sList);
//			u.setSkills(sList);
			
			user = manager.merge(user);
			skill = manager.merge(skill);
			
			user.getSkills().remove(skill);
			
//			String q = "UPDATE User u SET u.skills = :skill WHERE u = :user";
			
			manager.flush();
					
//			Query que = manager.createQuery(q);
//			
//			que.setParameter("skill", user.getSkills());
//			que.setParameter("user", user);
//			
//			return que.executeUpdate() > 0;
			return true;
		}
		catch (Exception e) {
			e.printStackTrace();
			return false;
		}
	}

}
